package com.dashan.backend.datastore;

import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.Query;

import com.dashan.backend.geosearch.GeoCell;
import com.google.appengine.api.datastore.Key;


public class PositionHistoryDao extends DaoBase {
    
    @SuppressWarnings("unchecked")
    public List<DsPosition> getPositionHistory(String userName) {
        Query query = pm.newQuery(DsPosition.class);
        query.setFilter(String.format("userName == userNameParam"));
        query.declareParameters("String userNameParam");
        query.setOrdering("timestamp desc");
        return (List<DsPosition>) query.execute(userName);
    }

    @SuppressWarnings("unchecked")
    public List<DsPosition> getCurrentPosition(String userName) {
        Query query = pm.newQuery(DsPosition.class);
        query.setFilter(String.format("userName == userNameParam && current == currentParam"));
        query.declareParameters("String userNameParam, boolean currentParam");
        query.setOrdering("timestamp desc");
        return (List<DsPosition>) query.execute(userName, true);
    }

    @SuppressWarnings("unchecked")
    public List<DsPosition> getPositionHistory(String userName, int count) {
        Query query = pm.newQuery(DsPosition.class);
        query.setFilter(String.format("userName == userNameParam"));
        query.declareParameters("String userNameParam");
        query.setOrdering("timestamp desc");
        query.setRange(0, count);
        return (List<DsPosition>) query.execute(userName);
    }
    
    @SuppressWarnings("unchecked")
    public List<DsPosition> getPositionHistory(String userName, Date from, Date to) {
        Query query = pm.newQuery(DsPosition.class);
        query.setFilter(String.format("userName == userNameParam && ",userName) + 
        "timestamp >= fromParam && timestamp <= toParam");
        query.declareImports("import java.util.Date");
        query.declareParameters("String userNameParam, Date fromParam, Date toParam");
        query.setOrdering("timestamp desc");

        return (List<DsPosition>) query.execute(userName, from, to);
    }
    
    public DsPosition getPosisionByKey(Key key) {
        return (DsPosition) pm.getObjectById(DsPosition.class, key);
    }
    
    public void addPosition(DsPosition position) {
        List<DsPosition> last = getCurrentPosition(position.getUserName());
        for (DsPosition p : last) {
            p.setCurrent(false);
            pm.makePersistent(p);
        }
        if (last.size() > 1) {
            Logger.getLogger(PositionHistoryDao.class.getName()).log(Level.WARNING, 
                    "More than one current position found, concurrency error!");
        }
        position.setCurrent(true);
        pm.makePersistent(position);
        pm.flush();
    }
    
    @SuppressWarnings("unchecked")
    public List<DsPosition> getPositionInCell(GeoCell cell, boolean currentOnly) {
        Query query = pm.newQuery(DsPosition.class);
        query.setOrdering("timestamp desc");
        if (currentOnly) {
            query.setFilter(String.format("dsGeoCellArray.%s == cellNumberParam " +
                    "&& current == currentParam", 
                    DsGeoCellArray.getFieldName(cell.getLevel())));
            query.declareParameters("Long cellNumberParam, boolean currentParam");            
            return (List<DsPosition>) query.execute(cell.getMortonNumber(), true);
        } else {
            query.setFilter(String.format("dsGeoCellArray.%s == cellNumberParam ", 
                    DsGeoCellArray.getFieldName(cell.getLevel())));
            query.declareParameters("Long cellNumberParam");            
            return (List<DsPosition>) query.execute(cell.getMortonNumber());
        }
        
    }
}
